package com.orm.util;

import com.spring.bean.BeanDefinition;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class ClassUtil {
	public static ClassLoader getClassLoader() {
		return ClassUtil.class.getClassLoader();
	}
	
	/**
	 * 加载某个类
	 *
	 * @param className 类全名
	 * @return
	 */
	public static Class<?> loadClass(String className) {
		try {
			Class<?> clazz = ClassUtil.class.getClassLoader().loadClass(className);
			return clazz;
		} catch (ClassNotFoundException e) {
			log.error("{} 类找不到,无法加载", className);
		}
		return null;
	}
	
	/**
	 * 用ClassLoader 加载资源
	 *
	 * @param filepath 文件路径
	 * @return 返回输入流
	 */
	public static InputStream getResource(String filepath) {
		InputStream resourceAsStream = ClassUtil.class.getClassLoader().getResourceAsStream(filepath);
		if (resourceAsStream == null) {
			log.error("{} 文件没有找到", filepath);
		}
		return resourceAsStream;
	}
	
	/**
	 * 返回泛型里面的实际类型，只能对单层泛型，非单层泛型直接原样返回
	 *
	 * @param genericReturnTypeString genericReturnType() 返回的
	 * @return 剥离掉外层后里层的类名
	 */
	public static String getReturnTypeString(String genericReturnTypeString) {
		Pattern compile = Pattern.compile("<(.*)>");
		Matcher matcher = compile.matcher(genericReturnTypeString);
		if (matcher.find()) {
			return matcher.group(1);
		}
		return genericReturnTypeString;
	}
	
	
	// public static Class<?> getType()
	
	public static void main(String[] args) {
		
		
		System.out.println(getReturnTypeString("java.util.List<java.lang.String>"));
	}
	
	
	// 取值
	public static Object getVal(Object target, String field) {
		Class<?> clazz = target.getClass();
		Field[] declaredFields = clazz.getDeclaredFields();
		
		try {
			for (Field f : declaredFields) {
				if (f.getName().equals(field)) {
					f.setAccessible(true);
					return f.get(target);
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	
	
	/**
	 * 查找该路径下所有的接口类路径
	 * @param scanPath
	 * @return
	 */
	public static Set<Class<?>> doScanClassName(String scanPath) {
		Set<Class<?>> mapperInterfaces = new HashSet<>(16);
		try {
			Enumeration<URL> resources = getClassLoader().getResources(scanPath.replace(".", "/"));      // 从类加载类拿到url路径
			while (resources.hasMoreElements()) {
				URL url = resources.nextElement();
				String decodePath = URLDecoder.decode(url.getPath(), "utf-8");    // URL路径如果含有中文 ，需要解码才能使用
				File rootFile = new File(decodePath);
				if (!rootFile.exists()) {
					continue;
				}
				
				File[] files = rootFile.listFiles();
				for (File file : files) {
					if (file.isDirectory()) {
						mapperInterfaces.addAll(doScanClassName(scanPath + "." + file.getName()));   // 递归调用下一层级扫描
					} else {
						if (file.isFile() && file.getName().endsWith(".class")) {
							String fullClassName = scanPath + "." + getClassSimpleName(file);
							Class<?> clazz = loadClass(fullClassName);
							
							if(clazz != null && clazz.isInterface()){
								mapperInterfaces.add(clazz);
							}
						}
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mapperInterfaces;
	}
	
	public static String getClassSimpleName(File f) {
		return f.getName().replace(".class", "");
	}
}
